﻿//-----------------------------------------------------------------------------
//<filedescription file="CreateTaskSequenceDialog.cs" company="Microsoft">
//  <copyright>
//     Copyright © Microsoft Corporation.  All rights reserved.
//     ***  DESIGNATED SAMPLE CODE (per the included software license terms) ***
//      THIS CODE SAMPLE IS MADE AVAILABLE TO YOU WITHOUT WARRANTY OF ANY KIND
//      AND CONFERS NO RIGHTS ON YOU WHATSOEVER EXCEPT THE RIGHT TO REVIEW IT
//      SOLELY AS A REFERENCE.  THE ENTIRE RISK OF USE OR RESULTS FROM USE OF
//      THIS CODE SAMPLE REMAINS WITH YOU.
//  </copyright>
//  <purpose>
//  
//  </purpose>
//  <notes>
//  </notes>
//</filedescription>
//-----------------------------------------------------------------------------


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.IO;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Xml.XPath;
using Microsoft.ConfigurationManagement.ManagementProvider;
using Microsoft.ConfigurationManagement.ManagementProvider.WqlQueryEngine;
using Microsoft.ConfigurationManagement.AdminConsole;
using Microsoft.ConfigurationManagement.AdminConsole.TaskSequenceEditor;
using Microsoft.ConfigurationManagement.AdminConsole.OsdCommon;
using Microsoft.ConfigurationManagement.IntegrationDevelopmentKit;

namespace Microsoft.ConfigurationManagement.IntegrationDevelopmentKit.CustomReboot
{
    /// <summary>
    /// 
    /// </summary>
    public partial class CreateTaskSequenceDialog : SmsCustomDialog
    {

        #region Properties

        #region OEM-specific properties

        private string deploymentWmiClassName;
        /// <summary>
        /// 
        /// </summary>
        public string DeploymentWmiClassName
        {
            get { return deploymentWmiClassName; }
            set { deploymentWmiClassName = value; }
        }

        private string rebootWmiClassName;
        /// <summary>
        /// 
        /// </summary>
        public string RebootWmiClassName
        {
            get { return rebootWmiClassName; }
            set { rebootWmiClassName = value; }
        }

        private string baseRegistryKey;
        /// <summary>
        /// 
        /// </summary>
        public string BaseRegistryKey
        {
            get { return baseRegistryKey; }
            set { baseRegistryKey = value; }
        }

        private string baseRegistryKey64;
        /// <summary>
        /// 
        /// </summary>
        public string BaseRegistryKey64
        {
            get { return baseRegistryKey64; }
            set { baseRegistryKey64 = value; }
        }

        private string oemName;
        /// <summary>
        /// 
        /// </summary>
        public string OemName
        {
            get { return oemName; }
            set { oemName = value; }
        }

        private string oemShortName;
        /// <summary>
        /// 
        /// </summary>
        public string OemShortName
        {
            get { return oemShortName; }
            set { oemShortName = value; }
        }

        #endregion

        private bool cboBusy = false;

        private WqlConnectionManager conn;

        /// <summary>
        /// 
        /// </summary>
        public WqlConnectionManager Connection
        {
            get { return conn; }
            set { conn = value; }
        }

        private SmsPageData pageData;
        /// <summary>
        /// 
        /// </summary>
        public SmsPageData MyPageData
        {
            get { return pageData; }
            set { pageData = value; }
        }

        private SmsFormData formData;
        /// <summary>
        /// 
        /// </summary>
        public SmsFormData MyFormData
        {
            get { return formData; }
            set { formData = value; }
        }

        private List<IResultObject> osList = new List<IResultObject>();
        private List<IResultObject> sysprepList = new List<IResultObject>();

        private XmlDocument taskSequenceXml = new XmlDocument();
        private XmlDocument templateXml = new XmlDocument();
        private XmlDocument configXml = new XmlDocument();

        private ToolTip toolTip1 = new ToolTip();

        private string selectedOsPackage;
        private string selectedOsConfigPackage;
        private string selectedSmsClientPackage;
        private bool isMergeAction = false;


        private int consoleFolderId = 0;
        /// <summary>
        ///     
        /// </summary>
        /// <value>
        ///     <para>
        ///         
        ///     </para>
        /// </value>
        /// <remarks>
        ///     
        /// </remarks>
        public int ConsoleFolderId
        {
            get { return consoleFolderId; }
            set { 
                consoleFolderId = value;
               // MessageBox.Show("ConsoleFolderID = " + consoleFolderId);
            }
        }

        /// <summary>
        ///     
        /// </summary>
        /// <remarks>
        ///     
        /// </remarks>
        public XmlDocument NewTaskSequenceXml = new XmlDocument();
        /// <summary>
        ///     
        /// </summary>
        /// <remarks>
        ///     
        /// </remarks>
        public string SelectedTaskSequenceName;
        /// <summary>
        ///     
        /// </summary>
        /// <remarks>
        ///     
        /// </remarks>
        public string TemplateFileName;
        /// <summary>
        ///     
        /// </summary>
        /// <remarks>
        ///     
        /// </remarks>
        public string SelectedUserAccount;
        /// <summary>
        ///     
        /// </summary>
        /// <remarks>
        ///     
        /// </remarks>
        public string SelectedUserPassword;
        

        #endregion

        #region Constants

        //======[ begin modification ]=======================
        // modified 9/4/08 by rhearn
        // - Added these constants to avoid using repetitive strings values in methods
        const string DUMMY_X86_BOOT_IMAGE_ID = "XXX00000";
        const string DUMMY_REBOOT_PACKAGE_ID = "XXX00001";
        const string DUMMY_OEM_TOOLKIT_PACKAGE_ID = "XXX00002";
        const string DUMMY_OS_INSTALL_PACKAGE_ID = "XXX00003";
        const string DUMMY_SMSCLIENT_PACKAGE_ID = "XXX00004";
        const string DUMMY_UNATTEND_PACKAGE_ID = "XXX00005";
        const string DUMMY_OS_IMAGE_PACKAGE_ID = "XXX00006";
        const string DUMMY_SYSPREP_PACKAGE_ID = "XXX00007";
        const string DUMMY_DATA_IMAGE_PACKAGE_ID = "XXX00008";
        const string DUMMY_DRIVER_PACKAGE_ID = "XXX00009";
        //======[ end modification ]=======================
        
        #endregion

        #region Constructors

        /// <summary>
        ///     
        /// </summary>
        public CreateTaskSequenceDialog()
        {
            InitializeComponent();
            SetupErrorProvider(); 
            SetupCustomProperties();
        }

        /// <summary>
        ///     
        /// </summary>
        /// <param name="connectionManager" type="Microsoft.ConfigurationManagement.ManagementProvider.ConnectionManagerBase">
        ///     <para>
        ///         
        ///     </para>
        /// </param>
        public CreateTaskSequenceDialog(ConnectionManagerBase connectionManager)
        {
            
        }


        //======[ begin modification ]================
        // modified 9/5/08 by rhearn
        // - Added this new constructor to allow for calling this form via the CustomRebootAction and TaskSequenceAction forms
        // - as part of a merge action, instead of just using this form for a *new* task sequence
        //

        /// <summary>
        ///     
        /// </summary>
        /// <param name="connectionManager" type="Microsoft.ConfigurationManagement.ManagementProvider.ConnectionManagerBase">
        ///     <para>
        ///         
        ///     </para>
        /// </param>
        /// <param name="currentTaskSequenceXml" type="System.Xml.XmlDocument">
        ///     <para>
        ///         
        ///     </para>
        /// </param>
        /// <param name="baseRegKey" type="string">
        ///     <para>
        ///         
        ///     </para>
        /// </param>
        /// <param name="templateFile" type="string">
        ///     <para>
        ///         
        ///     </para>
        /// </param>
        public CreateTaskSequenceDialog(ConnectionManagerBase connectionManager, XmlDocument currentTaskSequenceXml, string baseRegKey, string templateFile)
        {
            if (connectionManager == null)
            {
                throw new ArgumentNullException("connectionManager");
            }
            
            if (currentTaskSequenceXml == null)
            {
                throw new ArgumentNullException("currentTaskSequenceXml");
            }
            NewTaskSequenceXml = null;
            taskSequenceXml = currentTaskSequenceXml;
            isMergeAction = true;
            BaseRegistryKey64 = baseRegKey;
            TemplateFileName = templateFile;
            InitializeComponent();
            SetupErrorProvider();
            SetupCustomProperties();
            Connection = (WqlConnectionManager)connectionManager;
            ReadCurrentTaskSequenceSettings(currentTaskSequenceXml);
            FillForm();
            
        }
       
        
        //======[ end modification ]================
        


        /// <summary>
        /// 
        /// </summary>
        /// <param name="assembly"></param>
        /// <param name="formData"></param>
        /// <param name="pageData"></param>
        /// <returns></returns>
        public override bool Initialize(System.Reflection.Assembly assembly, SmsFormData formData, SmsPageData pageData)
        {
            base.Initialize(assembly, formData, pageData);
            Connection = (WqlConnectionManager)pageData.ConnectionManager;
            MyPageData = pageData;
            MyFormData = formData;
            FillForm();

            if ((pageData.PropertyManager != null) && (pageData.PropertyManager.ObjectClass == "SMS_ObjectContainerNode"))
            {
                ConsoleFolderId = pageData.PropertyManager["ContainerNodeID"].IntegerValue;
            }

            return true;
        } 



        #endregion

        #region Setup methods

        
        /// <summary>
        /// 
        /// </summary>
        protected virtual void SetupCustomProperties()
        {
            
        }

        //=======[ begin modification ]==============
        // Modified 9/4/08 by rhearn
        // - Added the ReadCurrentTaskSequenceSettings() method
        // - This method takes the current task sequence XML and sets properties (and control values) 
        // - based on the contents of the XML.

        private void ReadCurrentTaskSequenceSettings(XmlDocument currentTaskSequenceXml)
        {
            if (currentTaskSequenceXml == null)
            {
                throw new ArgumentNullException("currentTaskSequenceXml");
            }


            selectedOsPackage = string.Empty;
            selectedOsConfigPackage = string.Empty;
            
            selectedSmsClientPackage = string.Empty;
            
            XmlNode osInstallNode = null;
            osInstallNode = IntegrationKitUtilities.GetXmlNode(currentTaskSequenceXml, "//step[@type='SMS_TaskSequence_ApplyOperatingSystemAction']");
            if (osInstallNode != null)
            {
                XmlNode osImageNode = IntegrationKitUtilities.GetXmlNode(osInstallNode, "//variable[@name='ImagePackageID']");
                XmlNode osScriptNode = IntegrationKitUtilities.GetXmlNode(osInstallNode, "//variable[@name='InstallPackageID']");

                if (osImageNode != null)
                {
                    //this is an image-based install
                    selectedOsPackage = IntegrationKitUtilities.GetXmlNodeValue(osInstallNode, "//variable[@name='ImagePackageID']");
                    selectedOsConfigPackage = IntegrationKitUtilities.GetXmlNodeValue(osInstallNode, "//variable[@name='ConfigFilePackage']");
                }
                else if (osScriptNode != null)
                {
                    // this is a scripted OS install
                    selectedOsPackage = IntegrationKitUtilities.GetXmlNodeValue(osInstallNode, "//variable[@name='InstallPackageID']");
                    selectedOsConfigPackage = IntegrationKitUtilities.GetXmlNodeValue(osInstallNode, "//variable[@name='ConfigFilePackage']");
                }
                
            }
            else
            {
                // No OS installation was in the task sequence
                // Disable the OS install group controls
                grpOperatingSystem.Enabled = false;
                cmbOSPackage.Enabled = false;
                cmbSysprepPackage.Enabled = false;
                radScriptedInstall.Enabled = false;
                radWimImage.Enabled = false;
                lblInstallationType.Enabled = false;
            }


            XmlNode smsClientNode = null;
            smsClientNode = IntegrationKitUtilities.GetXmlNode(currentTaskSequenceXml, "//step[@type='SMS_TaskSequence_SetupWindowsAndSMSAction']");
            if (smsClientNode != null)
            {
                selectedSmsClientPackage = IntegrationKitUtilities.GetXmlNodeValue(smsClientNode, "//variable[@name='_SMSClientPackageID']");
            }

        }

        //=======[ end modification ]==============


        private void FillForm()
        {
            //=======[ begin modification ]==============
            // Modified 9/4/08 by rhearn
            // - Changed the following code to split out loading XML documents for better granularity
            //LoadXmlDocuments(BaseRegistryKey);
            configXml = LoadOemConfigXml(BaseRegistryKey64);
            templateXml = LoadTemplateXml(BaseRegistryKey64, TemplateFileName);
            //=======[ end modification ]==============
            

            FillConfigList();
            //=======[ begin modification ]==============
            // Modified 9/11/08 by rhearn
            // - Changed the following code to run only if the OS install group is enabled

            if (grpOperatingSystem.Enabled == true)
            {
                radWimImage.Checked = true;
                FillSysprepList();
            }
            //=======[ end modification ]==============

            //=======[ begin modification ]==============
            // Modified 9/4/08 by rhearn
            // - Changed the following code to use the public properties if set
            
            if (string.IsNullOrEmpty(SelectedTaskSequenceName))
            {
                txtTaskSequenceName.Text = Properties.Resources.Text_DefaultTaskSequenceName;
            }
            else
            {
                txtTaskSequenceName.Text = SelectedTaskSequenceName;
            }
            //txtTaskSequenceName.Text = Properties.Resources.Text_DefaultTaskSequenceName;
            //=======[ end modification ]==============

            txtPassword1.Text = Properties.Resources.Text_PasswordDefault;
            txtPassword2.Text = Properties.Resources.Text_PasswordVerifyDefault;
            txtUserName.Text = Properties.Resources.Text_UserAccountDefault;

            //=======[ begin modification ]==============
            // Modified 9/11/08 by rhearn
            // - Changed the following code to run only if the OS install group is enabled
            
            if (grpOperatingSystem.Enabled == true)
            {
                ValidateOsList();
                ValidateSysprepList();
            }
            //=======[ end modification ]==============

            ValidateUserName();
            ValidatePassword();
            txtTaskSequenceName.Focus();
        }

        private void FillOSList()
        {
            if (Connection == null)
            {
                MessageBox.Show("FillOSList: Connection not set yet.");
                return;
            }
            cboBusy = true;
            cmbOSPackage.Items.Clear();

            if (radWimImage.Checked == true)
            {
                osList = IntegrationKitUtilities.GetAllPackagesByType(Connection, IntegrationKitUtilities.PackageType.OSImagePackage);
            }
            else
            {
                osList = IntegrationKitUtilities.GetAllPackagesByType(Connection, IntegrationKitUtilities.PackageType.OSInstallPackage);
            }
            
            cmbOSPackage.Items.Insert(0, Properties.Resources.Text_Select);
            cmbOSPackage.Items.Add(Properties.Resources.Text_SelectLater);
            //MessageBox.Show("Added '" + Properties.Resources.Text_Select + "' to the OS package list.");
            //MessageBox.Show("Added '" + Properties.Resources.Text_SelectLater + "' to the OS package list.");
             

            if ((osList != null) && (osList.Count > 0))
            {
                List<IResultObject>.Enumerator listEnum = osList.GetEnumerator();
                
                while (listEnum.MoveNext())
                {
                    string osString = IntegrationKitUtilities.GetROStringProperty(listEnum.Current, "Name");
                    if (string.IsNullOrEmpty(osString) == false)
                    {
                        cmbOSPackage.Items.Add(osString);
                        //MessageBox.Show("Added '" + osString + "' to the OS package list.");
                    }
                }
            }

            cmbOSPackage.SelectedText = "";
            cmbOSPackage.SelectedIndex = 0;

            //====[ begin modification ]===========================
            // Modified 9/5/08 by rhearn
            // added the following code to allow for a merge action where OS package is already selected
            if (cmbOSPackage.Items.Contains(selectedOsPackage))
            {
                cmbOSPackage.SelectedItem = selectedOsPackage;
            }
            //====[ end modification ]============================

            cboBusy = false;
        }

        private void FillSysprepList()
        {
            if (cmbSysprepPackage.Enabled == true)
            {
                if (Connection == null)
                {
                    MessageBox.Show("FillSysprepList: Connection not set yet.");
                    return;
                }
                cboBusy = true;
                cmbSysprepPackage.Items.Clear();

                sysprepList = IntegrationKitUtilities.GetAllPackagesByType(Connection, IntegrationKitUtilities.PackageType.SWDPackage);

                cmbSysprepPackage.Items.Insert(0, Properties.Resources.Text_Select);
                cmbSysprepPackage.Items.Add(Properties.Resources.Text_SelectLater);
                //MessageBox.Show("Added '" + Properties.Resources.Text_Select + "' to the Sysprep package list.");
                //MessageBox.Show("Added '" + Properties.Resources.Text_SelectLater + "' to the Sysprep package list.");

                if ((sysprepList != null) && (sysprepList.Count > 0))
                {
                    List<IResultObject>.Enumerator listEnum = sysprepList.GetEnumerator();

                    while (listEnum.MoveNext())
                    {

                        string pkgString = IntegrationKitUtilities.GetROStringProperty(listEnum.Current, "Name");
                        if (string.IsNullOrEmpty(pkgString) == false)
                        {
                            cmbSysprepPackage.Items.Add(pkgString);
                            //MessageBox.Show("Added '" + pkgString + "' to the Sysprep package list.");
                        }
                    }

                    for (int k = 0; k < cmbSysprepPackage.Items.Count; k++)
                    {
                        
                    }
                }

                cmbSysprepPackage.SelectedIndex = 0;

                //====[ begin modification ]===========================
                // Modified 9/5/08 by rhearn
                // added the following code to allow for a merge action where sysprep package is already selected
                if (cmbSysprepPackage.Items.Contains(selectedOsConfigPackage))
                {
                    cmbSysprepPackage.SelectedItem = selectedOsConfigPackage;
                }
                //====[ end modification ]===========================
                
                cboBusy = false;
            }

        }

        private void FillConfigList()
        {
            
            XmlNodeList hardwareConfigs = IntegrationKitUtilities.GetXmlNodeList(configXml, "//HardwareConfigItems/HardwareConfigItem");
            if (hardwareConfigs == null)
            {
                clbServerConfigItems.Items.Add("Error loading names");
                MessageBox.Show("Error loading hardware config items from the configuration XML file");
                return;
            }
            foreach (XmlNode hardwareConfig in hardwareConfigs)
            {
                string configName = IntegrationKitUtilities.GetXmlNodeValue(hardwareConfig, ".//DisplayName");
                if (string.IsNullOrEmpty(configName) == false)
                {
                    clbServerConfigItems.Items.Add(configName);
                    //MessageBox.Show("Added '" + configName + "' to the configs list");
                }
            }
            ValidateConfigList();
            
            return;
        }


        //=======[ begin modification ]==============
        // Modified 9/4/08 by rhearn
        // - Split the LoadXmlDocuments() method into two methods for better granularity and to avoid global variables
        
        
        private XmlDocument LoadTemplateXml(string baseRegKey, string templateFileName)
        {
            string installDir = string.Empty;
            
            if (string.IsNullOrEmpty(templateFileName))
            {
                if (string.IsNullOrEmpty(BaseRegistryKey64))
                {
                    return null;
                }

                templateFileName = IntegrationKitUtilities.GetSafeRegistryStringValue("HKEY_LOCAL_MACHINE", BaseRegistryKey64, Properties.Resources.Registry_RebootTaskSequenceFullTemplate);

                if (File.Exists(templateFileName) == false)
                {
                    installDir = IntegrationKitUtilities.GetSafeRegistryStringValue("HKEY_LOCAL_MACHINE", BaseRegistryKey64, Properties.Resources.Registry_InstallationDirectory);

                    if (installDir.EndsWith("\\") == false)
                    {
                        installDir = installDir + "\\";
                    }
                    if (File.Exists(installDir + templateFileName))
                    {
                        templateFileName = installDir + templateFileName;
                    }
                } 
            }
            

          

            //===[ begin modification ]============================
            // Modified 9/4/08 by rhearn
            // - Changed variable name from templateXml to template to prevent conflict with existing property
            
            XmlDocument template = new XmlDocument();

            try
            {
                template.Load(templateFileName);
                //MessageBox.Show("XML File loaded.");
            }
            catch (XmlException ex)
            {
                MessageBox.Show("Exception occurred trying to load the task sequence template XML File" + ex.InnerException);
                //LogLine(string.Format(Properties.Resources.ErrorLog_XmlException, ex.TargetSite, ex.LineNumber, ex.LinePosition, ex.SourceUri, ex.Data, ex.InnerException, ex.GetType().Name, ex.GetType().FullName, ex.GetType().Attributes, ex.GetType().DeclaringMethod));
                return null;
            }
            return template;
            //===[ end modification ]=========================
        }

        private XmlDocument LoadOemConfigXml(string baseRegKey)
        {
            try
            {
                // 
                // Loads an XML file, which is by default stored in a directory on the site
                // server under the Deployment Pack install path. The path is saved in
                // a registry key during installation.
                //
                string XMLFile = IntegrationKitUtilities.GetSafeRegistryStringValue("HKEY_LOCAL_MACHINE", baseRegKey, Properties.Resources.Registry_XMLConfigurationFile);

                string installDir = IntegrationKitUtilities.GetSafeRegistryStringValue("HKEY_LOCAL_MACHINE", baseRegKey, Properties.Resources.Registry_InstallationDirectory);

                if (string.IsNullOrEmpty(installDir))
                {
                    MessageBox.Show(string.Format("LoadOemConfigXml: " + Properties.Resources.LoadXmlDocument_InstallDirKeyNotFound, baseRegKey + "\\" + Properties.Resources.Registry_InstallationDirectory, installDir));
                    return null;
                }

                if (string.IsNullOrEmpty(XMLFile))
                {
                    MessageBox.Show("LoadOemConfigXml: " + Properties.Resources.LoadXmlDocument_ConfigXmlKeyNotFound, baseRegKey + "\\" + Properties.Resources.Registry_XMLConfigurationFile);
                    return null;
                }

                if (Directory.Exists(installDir) == false)
                {
                    MessageBox.Show(string.Format("LoadOemConfigXml: " + Properties.Resources.LoadXmlDocument_InstallDirNotFound, baseRegKey + "\\" + Properties.Resources.Registry_InstallationDirectory, installDir));
                    return null;
                }

                if (File.Exists(XMLFile) == false)
                {
                    // the registry key had a value but we could not find the file. Perhaps the key only specifies a filename?
                    if (XMLFile.Contains(@"\") == false)
                    {
                        // looks like this is just a filename. Try adding the path.
                        if (installDir.EndsWith(@"\") == false)
                        {
                            installDir += @"\";
                        }
                        XMLFile = installDir + XMLFile;

                    }
                    if (File.Exists(XMLFile) == false)
                    {
                        MessageBox.Show(string.Format("LoadOemConfigXml: " + Properties.Resources.LoadXmlDocument_ConfigXmlNotFound, baseRegKey + "\\" +
                            Properties.Resources.Registry_XMLConfigurationFile, baseRegKey + "\\" +
                            Properties.Resources.Registry_InstallationDirectory, installDir));
                        return null;
                    }

                }

                XmlDocument Xmldoc = new XmlDocument();

                try
                {
                    Xmldoc.Load(XMLFile);
                }
                catch (XmlException ex)
                {
                    MessageBox.Show(string.Format("XML Exception occurred loading configuration XML file", ex.TargetSite, ex.LineNumber, ex.LinePosition, ex.SourceUri, ex.Data, ex.InnerException, ex.GetType().Name, ex.GetType().FullName, ex.GetType().Attributes, ex.GetType().DeclaringMethod));
                    return null;
                }

                // if program execution has not jumped to the catch statement here, the XML file was successfully loaded, 
                // so return the XML document object.
                return Xmldoc;
            }
            catch (Exception e)
            {
                MessageBox.Show("LoadOemConfigXml: Exception occurred: " + e.Message + "\n" + e.StackTrace);
                return null;
            }

        }


        //=======[ end modification ]==============



        #region ===[ Modification (removed code) 9/4/08) ]===
        
        //private XmlDocument LoadXmlDocuments(string baseRegistryKey)
        //{
        //    // 
        //    // Loads XML config file, which is by default stored in a directory on the site
        //    // server under the Deployment Pack install path. The path is saved in
        //    // a registry key during installation.
        //    //
        //    string configFileName = string.Empty;
        //    // modified 09/05/08 by rhearn - commented out following variable to use the public property instead
        //    //string templateFileName = string.Empty;
        //    string installDir = string.Empty;

            
        //    try
        //    {
        //        configFileName = (string)Microsoft.Win32.Registry.GetValue(baseRegistryKey, Properties.Resources.Registry_XMLConfigurationFile, null);
        //    }
        //    catch (NullReferenceException)
        //    {
        //        MessageBox.Show("Exception occurred when trying to access the registry key:\n" + baseRegistryKey +
        //            Properties.Resources.Registry_XMLConfigurationFile + "\nPlease check your installation.");
        //        return null;
        //    }
            
        //    // modified 09/05/08 by rhearn - added the IF statement to use the public property if it exists
        //    if (string.IsNullOrEmpty(TemplateFileName))
        //    {
        //        try
        //        {
        //            TemplateFileName = (string)Microsoft.Win32.Registry.GetValue(baseRegistryKey, Properties.Resources.Registry_RebootTaskSequenceFullTemplate, null);
        //        }
        //        catch (NullReferenceException)
        //        {
        //            MessageBox.Show("Exception occurred when trying to access the registry key:\n" + baseRegistryKey +
        //                Properties.Resources.Registry_RebootTaskSequenceFullTemplate + "\nPlease check your installation.");
        //            return null;
        //        }
        //    }
        //    // end modification

        //    try
        //    {
        //        installDir = (string)Microsoft.Win32.Registry.GetValue(baseRegistryKey, Properties.Resources.Registry_InstallationDirectory, null);
        //        if (string.IsNullOrEmpty(installDir))
        //        {
        //            MessageBox.Show("Installation directory not found.");
        //            return null;
        //        }
        //        if (Directory.Exists(installDir) == false)
        //        {
        //            MessageBox.Show("Installation directory not found.");
        //            return null;
        //        }
        //    }
        //    catch (NullReferenceException)
        //    {
        //        MessageBox.Show("Exception occurred when trying to access the registry key:\n" + baseRegistryKey +
        //            Properties.Resources.Registry_InstallationDirectory + "\nPlease check your installation.");
        //        return null;
        //    }

           

        //    if (File.Exists(configFileName) == false)
        //    {
        //        // the registry key had a value but we could not find the file. Perhaps the key only specifies a filename?
        //        if (configFileName.Contains(@"\") == false)
        //        {
        //            // looks like this is just a filename. Try adding the path.
        //            if (installDir.EndsWith(@"\") == false)
        //            {
        //                installDir += @"\";
        //            }
        //            configFileName = installDir + configFileName;
        //            //MessageBox.Show("XmlFile location = " + XMLFile);
                
        //        }
        //        if (File.Exists(configFileName) == false)
        //        {
        //            MessageBox.Show("XML config file not found: " + configFileName);
        //            return null;
        //        }
        //    }

        //    if (File.Exists(TemplateFileName) == false)
        //    {
        //        // the registry key had a value but we could not find the file. Perhaps the key only specifies a filename?
        //        if (TemplateFileName.Contains(@"\") == false)
        //        {
        //            // looks like this is just a filename. Try adding the path.
        //            if (installDir.EndsWith(@"\") == false)
        //            {
        //                installDir += @"\";
        //            }
        //            TemplateFileName = installDir + TemplateFileName;
        //            //MessageBox.Show("XmlFile location = " + XMLFile);

        //        }
        //        if (File.Exists(TemplateFileName) == false)
        //        {
        //            MessageBox.Show("XML task sequence template file not found: " + TemplateFileName);
        //            return null;
        //        }
        //    }

            
        //    try
        //    {
        //        configXml.Load(configFileName);
        //        //MessageBox.Show("XML File loaded.");
                
        //    }
        //    catch (XmlException ex)
        //    {
        //        MessageBox.Show("Exception occurred trying to load the configuration XML File\n"+ ex.InnerException);
        //        //LogLine(string.Format(Properties.Resources.ErrorLog_XmlException, ex.TargetSite, ex.LineNumber, ex.LinePosition, ex.SourceUri, ex.Data, ex.InnerException, ex.GetType().Name, ex.GetType().FullName, ex.GetType().Attributes, ex.GetType().DeclaringMethod));
        //        return null;
        //    }

        //    try
        //    {
        //        taskSequenceXml.Load(TemplateFileName);
        //        //MessageBox.Show("XML File loaded.");

        //    }
        //    catch (XmlException ex)
        //    {
        //        MessageBox.Show("Exception occurred trying to load the configuration XML File" + ex.InnerException);
        //        //LogLine(string.Format(Properties.Resources.ErrorLog_XmlException, ex.TargetSite, ex.LineNumber, ex.LinePosition, ex.SourceUri, ex.Data, ex.InnerException, ex.GetType().Name, ex.GetType().FullName, ex.GetType().Attributes, ex.GetType().DeclaringMethod));
        //        return null;
        //    }

        //    // if program execution has not jumped to the catch statement here, the XML file was successfully loaded, 
        //    // so return the XML document object.
            
        //    return configXml;
        //}
        
        #endregion

        /// <summary>
        /// 
        /// </summary>
        protected virtual void SetupErrorProvider()
        {
            try
            {
                epOsList = new ErrorProvider();
                epOsList.SetIconAlignment(cmbOSPackage, ErrorIconAlignment.MiddleRight);
                epOsList.SetIconPadding(cmbOSPackage, 2);
                epOsList.BlinkStyle = ErrorBlinkStyle.NeverBlink;

                epPassword1 = new ErrorProvider();
                epPassword1.SetIconAlignment(txtPassword1, ErrorIconAlignment.MiddleRight);
                epPassword1.SetIconPadding(txtPassword1, 2);
                epPassword1.BlinkStyle = ErrorBlinkStyle.NeverBlink;

                epPassword2 = new ErrorProvider();
                epPassword2.SetIconAlignment(txtPassword2, ErrorIconAlignment.MiddleRight);
                epPassword2.SetIconPadding(txtPassword2, 2);
                epPassword2.BlinkStyle = ErrorBlinkStyle.NeverBlink;

                epSysprep = new ErrorProvider();
                epSysprep.SetIconAlignment(cmbSysprepPackage, ErrorIconAlignment.MiddleRight);
                epSysprep.SetIconPadding(cmbSysprepPackage, 2);
                epSysprep.BlinkStyle = ErrorBlinkStyle.NeverBlink;

                epUserAccount = new ErrorProvider();
                epUserAccount.SetIconAlignment(txtUserName, ErrorIconAlignment.MiddleRight);
                epUserAccount.SetIconPadding(txtUserName, 2);
                epUserAccount.BlinkStyle = ErrorBlinkStyle.NeverBlink;

                //====[ modified 12/16/08 by rhearn to add a new error provider ]============//
                epConfigList = new ErrorProvider();
                epConfigList.SetIconAlignment(clbServerConfigItems, ErrorIconAlignment.MiddleRight);
                epConfigList.SetIconPadding(clbServerConfigItems, 2);
                epConfigList.BlinkStyle = ErrorBlinkStyle.NeverBlink;


            }
            catch (Exception e)
            {
                //LogException(e);
                MessageBox.Show("Exception occurred while setting up error providers.\n" + e.InnerException);
            }
        }


        #endregion

        #region Processing Methods

        //==========[ begin modification]================
        // modified 9/5/08 by rhearn
        // - Added the following method to compartmentalize template modification based on UI values
        // - so that code is not duplicated in several other methods     
        
        
        private XmlDocument RemoveUnusedStepsFromTemplate(XmlDocument template, XmlDocument oemConfigXml, CheckedListBox.CheckedItemCollection checkedOemItems, bool scriptedInstall)
        {
            if (template == null)
            {
                throw new ArgumentNullException("templateXml");
            }
            if (oemConfigXml == null)
            {
                throw new ArgumentNullException("oemConfigXml");
            }
            if (checkedOemItems == null)
            {
                throw new ArgumentNullException("checkedOemItems");
            }

            // get the task sequence template XML and remove items not being used, including:
            //  - unused OEM configuration tasks
            //  - either the OS imaging task or the OS scripted install task
            //    (and replace the package ID info for the OS install task & sysprep)

            XmlNodeList oemSteps = IntegrationKitUtilities.GetXmlNodeList(template, "//step[@type='" + DeploymentWmiClassName + "']");
            if (oemSteps != null)
            {
                XmlNode oemStep = null;
                for (int i = 0; i < oemSteps.Count; i++)
                {
                    bool found = false;
                    oemStep = oemSteps[i];
                    string stepName = IntegrationKitUtilities.GetXmlAttribute(oemStep, "name");
                    XmlNodeList hardwareConfigsXml = IntegrationKitUtilities.GetXmlNodeList(oemConfigXml, "//HardwareConfigItem");
                    if (hardwareConfigsXml == null)
                    {
                        break;
                    }
                    string actionName = string.Empty;
                    foreach (XmlNode hardwareConfigXml in hardwareConfigsXml)
                    {
                        string actionNameXml = IntegrationKitUtilities.GetXmlNodeValue(hardwareConfigXml, ".//ActionName");
                        if (stepName.IndexOf(actionNameXml, 0, StringComparison.OrdinalIgnoreCase) > 0)
                        {
                            actionName = IntegrationKitUtilities.GetXmlNodeValue(hardwareConfigXml, ".//DisplayName");
                            break;
                        }
                    }

                    if (string.IsNullOrEmpty(actionName) == false)
                    {
                        foreach (object itemChecked in checkedOemItems)
                        {
                            if (string.Compare(itemChecked.ToString(), actionName, StringComparison.OrdinalIgnoreCase) == 0)
                            {
                                found = true;
                                //MessageBox.Show("Found OEM step to run: " + oemStep.OuterXml);
                            }
                        }
                        if (found == false)
                        {
                            XmlNode oemStepParent = oemStep.ParentNode;
                            if (oemStepParent != null)
                            {
                                oemStepParent.RemoveChild(oemStep);
                                //i -= 1;
                            }
                            //MessageBox.Show("Removed oem step: " + oemStep.OuterXml);
                        }
                    }
                }
            }
            // (else) no OEM steps were found in the template (this should not happen)

            XmlNode osRemoveXml = null;
            if (scriptedInstall == true)
            {
                //scripted install is checked, so the image-based install task will be selected and removed
                osRemoveXml = IntegrationKitUtilities.GetXmlNode(template, "//step[@type='SMS_TaskSequence_ApplyOperatingSystemAction'][@name='Apply Operating System Image']");
            }
            else
            {
                // image-based install is checked, so the scripted install task will be selected and removed
                osRemoveXml = IntegrationKitUtilities.GetXmlNode(template, "//step[@type='SMS_TaskSequence_ApplyOperatingSystemAction'][@name='Apply Operating System']");
            }
            if (osRemoveXml != null)
            {
                osRemoveXml.ParentNode.RemoveChild(osRemoveXml);
            }


            return template;

        }
        
        
        //==========[ end modification]================


        //==========[ begin modification]================
        // modified 9/5/08 by rhearn
        // - Added the following method to compartmentalize template modification based on UI values
        // - so that code is not duplicated in several other methods     
        
        private XmlDocument ReplaceSelectionPackageIds(XmlDocument template)
        {
            if (template == null)
            {
                throw new ArgumentNullException("templateXml");
            }


            // replace the package IDs for the OS Image (or OS Scripted Install) package
            // as well as the Sysprep/Unattend package

            string osPackageId = GetSelectedPackageId(cmbOSPackage);
            string sysprepPackageId = GetSelectedPackageId(cmbSysprepPackage);

            //MessageBox.Show("osPackageId = " + osPackageId);
            //MessageBox.Show("sysprepPackageId = " + sysprepPackageId);

            string taskSequenceString = template.OuterXml;

            if (string.IsNullOrEmpty(osPackageId) == false)
            {
                taskSequenceString = taskSequenceString.Replace(DUMMY_OS_INSTALL_PACKAGE_ID, osPackageId);       // the dummy ID for OSInstallPackage
                taskSequenceString = taskSequenceString.Replace(DUMMY_OS_IMAGE_PACKAGE_ID, osPackageId);       // the dummy ID for OSImagePackage
            }

            if (string.IsNullOrEmpty(sysprepPackageId) == false)
            {
                taskSequenceString = taskSequenceString.Replace(DUMMY_UNATTEND_PACKAGE_ID, sysprepPackageId);  // the dummy ID for Sysprep package
                taskSequenceString = taskSequenceString.Replace(DUMMY_SYSPREP_PACKAGE_ID, sysprepPackageId);  // the dummy ID for Unattend package
            }

            if (string.IsNullOrEmpty(taskSequenceString) == false)
            {
                template.RemoveAll();
                template.LoadXml(taskSequenceString);
            }


            return template;
        }
        
        //==========[ end modification]================


        //==========[ begin modification]================
        // modified 9/5/08 by rhearn
        // - Added the following method to create a standard reusable method for creating a new task sequence from the new XML

        private IResultObject CreateTaskSequenceFromUpdatedTemplate(XmlDocument template)
        {
            
            // Get the boot image package ID 
            string bootImageId = string.Empty;
            bootImageId = CustomRebootUtils.GetPackageIdFromReplacementString(Connection, configXml, DUMMY_X86_BOOT_IMAGE_ID);


            // Create an SMS_TaskSequence object from the XML template
            IResultObject taskSequence = IntegrationKitUtilities.CreateTaskSequenceFromXml(Connection, template);
            if (taskSequence == null)
            {
                MessageBox.Show("CreateTaskSequenceTemplate: Unable to create an instance of SMS_TaskSequence.");
                return null;
            }


            // update the task sequence object with the user-selected account name and password
            taskSequence = CustomRebootUtils.UpdateUserNameAndPasswordInRebootTask(taskSequence, RebootWmiClassName, txtUserName.Text, txtPassword1.Text);
            if (taskSequence == null)
            {
                MessageBox.Show("CreateTaskSequenceTemplate: Unable to update the username and password in the task sequence actions");
                return null;
            }

            
            // create a new empty SMS_TaskSequencePackage object to hold the task sequence
            IResultObject taskSequencePackage = IntegrationKitUtilities.CreateTaskSequencePackage(Connection);
            if (taskSequencePackage == null)
            {
                MessageBox.Show("CreateTaskSequenceTemplate: Unable to create an instance of SMS_TaskSequencePackage.");
                return null;
            }

            // Set the name of the new task sequence package using the value on the dialog or the default.
            if (string.IsNullOrEmpty(txtTaskSequenceName.Text))
            {
                taskSequencePackage["Name"].StringValue = Properties.Resources.Text_DefaultTaskSequenceName;
                txtTaskSequenceName.Text = Properties.Resources.Text_DefaultTaskSequenceName;
            }
            else
            {
                taskSequencePackage["Name"].StringValue = txtTaskSequenceName.Text;
            }

            // add the task sequence to the new task sequence package
            taskSequencePackage = IntegrationKitUtilities.AddTaskSequenceToPackage(Connection, taskSequencePackage, taskSequence);
            if (taskSequencePackage == null)
            {
                MessageBox.Show("CreateTaskSequenceTemplate: Unable to add the task sequence to the Task Sequence Package."); 
                return null;
            }


            // search for any existing task sequence packages with the same name as the new package
            IResultObject testPackage =
                IntegrationKitUtilities.GetPackageByName(
                Connection,
                taskSequencePackage["Name"].StringValue,
                IntegrationKitUtilities.PackageType.TaskSequencePackage,
                null);
            if (testPackage != null)
            {
                //that name is already taken. Generate a new unique name.

                // need to shorten the current name if adding the package ID will make it > 50 characters.
                string newTsName = txtTaskSequenceName.Text;
                if (newTsName.Length > 39)
                {
                    newTsName = newTsName.Remove(39);
                }
                taskSequencePackage["Name"].StringValue = newTsName + " - " +
                    IntegrationKitUtilities.GetROStringProperty(taskSequencePackage, "PackageID");
            }

            // Now add the other properties to the task sequence package and save it.
            taskSequencePackage["BootImageID"].StringValue = bootImageId;
            taskSequencePackage["Duration"].IntegerValue = 360;
            taskSequencePackage["Description"].StringValue = "";
            taskSequencePackage["Category"].StringValue = "";
            taskSequencePackage.Put();

            if (taskSequencePackage == null)
            {
                //mergeErrorOccurred = true;
                return null;
            }

            return taskSequencePackage;
            
        }


        //==========[ end modification]================

        #region ===[ Modification (removed code) 9/5/08 ]===


        //==========[ begin modification]================
        // modified 9/5/08 by rhearn
        // - Changed to use more generic methods and moved method calls to btnCreate_Click
        //
        //private IResultObject CreateTaskSequenceTemplate(XmlDocument templateXml)
        //{
        //    //MessageBox.Show("CreateTaskSequenceTemplate: Starting...");
                
        //    if (Connection == null)
        //    {
        //        MessageBox.Show("CreateTaskSequenceTemplate: Connection to SCCM server not set yet.");
        //        return null;
        //    }

        //    try
        //    {
        //        #region ==[modification (removed) 9/4/08]===
        //        //==========[ begin modification]================
        //        // Modified 9/5/08 by rhearn
        //        // - Removed this section of code and created a new method (RemoveUnusedStepsFromTemplate())

        //            //// get the task sequence template XML and remove items not being used, including:
        //            ////  - unused OEM configuration tasks
        //            ////  - either the OS imaging task or the OS scripted install task
        //            ////    (and replace the package ID info for the OS install task & sysprep)

        //            //XmlNodeList oemSteps = IntegrationKitUtilities.GetXmlNodeList(taskSequenceXml, "//step[@type='" + DeploymentWmiClassName + "']");
        //            //if (oemSteps != null)
        //            //{
        //            //    XmlNode oemStep = null;
        //            //    for (int i = 0; i < oemSteps.Count; i++ )
        //            //    {
        //            //        bool found = false;
        //            //        oemStep = oemSteps[i];
        //            //        string stepName = IntegrationKitUtilities.GetXmlAttribute(oemStep, "name");
        //            //        XmlNodeList hardwareConfigsXml = IntegrationKitUtilities.GetXmlNodeList(configXml, "//HardwareConfigItem");
        //            //        if (hardwareConfigsXml == null)
        //            //        {
        //            //            break;
        //            //        }
        //            //        string actionName = string.Empty;
        //            //        foreach (XmlNode hardwareConfigXml in hardwareConfigsXml)
        //            //        {
        //            //            string actionNameXml = IntegrationKitUtilities.GetXmlNodeValue(hardwareConfigXml, ".//ActionName");
        //            //            if (stepName.IndexOf(actionNameXml,0, StringComparison.OrdinalIgnoreCase) > 0)
        //            //            {
        //            //                actionName = IntegrationKitUtilities.GetXmlNodeValue(hardwareConfigXml, ".//DisplayName");
        //            //                break;
        //            //            }
        //            //        }

        //            //        if (string.IsNullOrEmpty(actionName) == false)
        //            //        {
        //            //            foreach (object itemChecked in clbServerConfigItems.CheckedItems)
        //            //            {
        //            //                if (string.Compare(itemChecked.ToString(), actionName, StringComparison.OrdinalIgnoreCase) == 0)
        //            //                {
        //            //                    found = true;
        //            //                    //MessageBox.Show("Found OEM step to run: " + oemStep.OuterXml);
        //            //                }
        //            //            }
        //            //            if (found == false)
        //            //            {
        //            //                XmlNode oemStepParent = oemStep.ParentNode;
        //            //                if (oemStepParent != null)
        //            //                {
        //            //                    oemStepParent.RemoveChild(oemStep);
        //            //                    //i -= 1;
        //            //                }
        //            //                //MessageBox.Show("Removed oem step: " + oemStep.OuterXml);
        //            //            }
        //            //        }
        //            //    }
        //            //}


        //        //==========[ end modification]================
        //        #endregion

        //        //==========[ begin modification]================
        //        // Modified 9/5/08 by rhearn
        //        // - Replacement method call for the above removed code
        //        templateXml = RemoveUnusedStepsFromTemplate(templateXml, configXml, clbServerConfigItems.CheckedItems, radScriptedInstall.Checked);
        //        //==========[ end modification]================


        //        #region ==[modification (removed) 9/4/08]===

        //        //==========[ begin modification]================
        //        // Modified 9/5/08 by rhearn
        //        // - Removed this section of code and created a new method (ReplaceSelectionPackageIds())

        //            //// replace the package IDs for the OS Image (or OS Scripted Install) package
        //            //// as well as the Sysprep/Unattend package
                    
        //            //string osPackageId = GetSelectedPackageId(cmbOSPackage);
        //            //string sysprepPackageId = GetSelectedPackageId(cmbSysprepPackage);

        //            ////MessageBox.Show("osPackageId = " + osPackageId);
        //            ////MessageBox.Show("sysprepPackageId = " + sysprepPackageId);

        //            //string taskSequenceString = taskSequenceXml.OuterXml;

        //            //if (string.IsNullOrEmpty(osPackageId)== false) 
        //            //{
        //            //    taskSequenceString = taskSequenceString.Replace(DUMMY_OS_INSTALL_PACKAGE_ID, osPackageId);       // the dummy ID for OSInstallPackage
        //            //    taskSequenceString = taskSequenceString.Replace(DUMMY_OS_IMAGE_PACKAGE_ID, osPackageId);       // the dummy ID for OSImagePackage
        //            //}

        //            //if (string.IsNullOrEmpty(sysprepPackageId) == false)
        //            //{
        //            //    taskSequenceString = taskSequenceString.Replace(DUMMY_UNATTEND_PACKAGE_ID, sysprepPackageId);  // the dummy ID for Sysprep package
        //            //    taskSequenceString = taskSequenceString.Replace(DUMMY_SYSPREP_PACKAGE_ID, sysprepPackageId);  // the dummy ID for Unattend package
        //            //}

        //            //if (string.IsNullOrEmpty(taskSequenceString) == false)
        //            //{
        //            //    taskSequenceXml.RemoveAll();
        //            //    taskSequenceXml.LoadXml(taskSequenceString);
        //            //}


        //        // - Removed this section of code and put it in RemoveUnusedStepsFromTemplate()

        //            //XmlNode osRemoveXml = null;
        //            //if (radScriptedInstall.Checked == true)
        //            //{
        //            //    //scripted install is checked, so the image-based install task will be selected and removed
        //            //    osRemoveXml = IntegrationKitUtilities.GetXmlNode(taskSequenceXml, "//step[@type='SMS_TaskSequence_ApplyOperatingSystemAction'][@name='Apply Operating System Image']");
        //            //}
        //            //else
        //            //{
        //            //    // image-based install is checked, so the scripted install task will be selected and removed
        //            //    osRemoveXml = IntegrationKitUtilities.GetXmlNode(taskSequenceXml, "//step[@type='SMS_TaskSequence_ApplyOperatingSystemAction'][@name='Apply Operating System']");
        //            //}
        //            //if (osRemoveXml != null)
        //            //{
        //            //    osRemoveXml.ParentNode.RemoveChild(osRemoveXml);
        //            //}
        //        //==========[ end modification]================
                
        //        #endregion

        //        //==========[ begin modification]================
        //        // Modified 9/5/08 by rhearn
        //        // - Replacement method call for the above removed code
        //        templateXml = ReplaceSelectionPackageIds(templateXml);
        //        //==========[ end modification]================


        //        templateXml = CustomRebootUtils.FixPackageReferencesInTaskSequence(Connection, templateXml, configXml);
                

        //        #region ===[ Modification (removed code) 9/4/08) ]===
        //        //==========[ begin modification]================
        //        // Modified 9/5/08 by rhearn
        //        // - Removed this section of code and created a new method (CreateTaskSequenceFromUpdatedTemplate())


        //            //// Create the task sequence from the XML
        //            //string bootImageId = string.Empty;
        //            //XmlNode topTaskSequenceNode = IntegrationKitUtilities.GetXmlNode(templateXml, "//SmsTaskSequencePackage");
        //            //if (topTaskSequenceNode != null)
        //            //{
        //            //    bootImageId = IntegrationKitUtilities.GetXmlNodeValue(topTaskSequenceNode, "//BootImageID");
        //            //}

        //            //IResultObject taskSequence = IntegrationKitUtilities.CreateTaskSequenceFromXml(Connection, templateXml);
        //            //if (taskSequence == null)
        //            //{
        //            //    MessageBox.Show("CreateTaskSequenceTemplate: Unable to create an instance of SMS_TaskSequence.");
        //            //    return null;
        //            //}

        //            //// update the task sequence with the user-selected account name and password
        //            //taskSequence = CustomRebootUtils.UpdateUserNameAndPasswordInRebootTask(taskSequence, RebootWmiClassName, txtUserName.Text, txtPassword1.Text);
        //            //if (taskSequence == null)
        //            //{
        //            //    MessageBox.Show("CreateTaskSequenceTemplate: Unable to update the username and password in the task sequence actions");
        //            //    return null;
        //            //}

        //            ////MessageBox.Show("CreateTaskSequenceTemplate: Successfully created an instance of SMS_TaskSequence from the XML");

        //            //IResultObject taskSequencePackage = IntegrationKitUtilities.CreateTaskSequencePackage(Connection, taskSequence);
        //            //if (taskSequencePackage == null)
        //            //{
        //            //    MessageBox.Show("CreateTaskSequenceTemplate: Unable to create an instance of SMS_TaskSequencePackage.");
        //            //    return null;
        //            //}

        //            //if (string.IsNullOrEmpty(txtTaskSequenceName.Text))
        //            //{
        //            //    taskSequencePackage["Name"].StringValue = Properties.Resources.Text_DefaultTaskSequenceName;
        //            //    txtTaskSequenceName.Text = Properties.Resources.Text_DefaultTaskSequenceName;
        //            //}
        //            //else
        //            //{
        //            //    taskSequencePackage["Name"].StringValue = txtTaskSequenceName.Text;
        //            //}

        //            //taskSequencePackage = IntegrationKitUtilities.AddTaskSequenceToPackage(Connection, taskSequencePackage, taskSequence);
        //            //if (taskSequencePackage == null)
        //            //{
        //            //    return null;
        //            //}

        //            //IResultObject testPackage =
        //            //    IntegrationKitUtilities.GetPackageByName(
        //            //    Connection,
        //            //    taskSequencePackage["Name"].StringValue,
        //            //    IntegrationKitUtilities.PackageType.TaskSequencePackage,
        //            //    null);
        //            //if (testPackage != null)
        //            //{
        //            //    //that name is already taken. Generate a new unique name.

        //            //    // need to shorten the current name if adding the package ID will make it > 50 characters.
        //            //    string newTsName = txtTaskSequenceName.Text;
        //            //    if (newTsName.Length > 39)
        //            //    {
        //            //        newTsName = newTsName.Remove(39);
        //            //    }
        //            //    taskSequencePackage["Name"].StringValue = newTsName + " - " +
        //            //        IntegrationKitUtilities.GetROStringProperty(taskSequencePackage, "PackageID");
        //            //}

        //            ////MessageBox.Show("CreateTaskSequenceTemplate: Task sequence name = " + taskSequencePackage["Name"].StringValue);
        //            //taskSequencePackage["BootImageID"].StringValue = bootImageId;
        //            //taskSequencePackage["Duration"].IntegerValue = 360;
        //            //taskSequencePackage["Description"].StringValue = "";
        //            //taskSequencePackage["Category"].StringValue = "";
        //            //taskSequencePackage.Put();

        //        //==========[ end modification]================

        //        #endregion

        //        //==========[ begin modification]================
        //        // Modified 9/5/08 by rhearn
        //        // - Replacement method call for the above removed code plus additional error checking
        //        IResultObject taskSequencePackage = CreateTaskSequenceFromUpdatedTemplate(templateXml);
        //        if (taskSequencePackage == null)
        //        {
        //            MessageBox.Show("CreateTaskSequenceTemplate: Could not create task sequence package!");
        //            return null;
        //        }
                
        //        //==========[ end modification]================

                               
        //        return taskSequencePackage;

        //    }
        //    catch (SmsException e)
        //    {
        //        MessageBox.Show(Properties.Resources.CTS_Exception_CreatingTaskSequence + "\n" + e.Message + e.InnerException + e.Details);
        //        return null;
        //    }
        //}

        //==========[ end modification]================

        #endregion

        private string GetSelectedPackageId(ComboBox combo)
        {
            if (combo.Tag != null)
            {
                IResultObject pkg = (IResultObject)combo.Tag;
                if (pkg != null)
                {
                    return IntegrationKitUtilities.GetROStringProperty(pkg, "PackageID");
                }
            }
            return string.Empty;
        }

        /// <summary>
        ///     
        /// </summary>
        /// <param name="type" type="string">
        ///     <para>
        ///         
        ///     </para>
        /// </param>
        /// <param name="title" type="string">
        ///     <para>
        ///         
        ///     </para>
        /// </param>
        /// <param name="content" type="string">
        ///     <para>
        ///         
        ///     </para>
        /// </param>
        protected void ShowFileViewerDialog(string type, string title, string content)
        {
            FileViewer fv = new FileViewer();
            fv.Height = 200;
            fv.Width = 200;
            

            fv.Text = title;
            if (type.ToLower() == "text")
            {
                fv.EditText = content;
            }
            else
            {
                fv.EditHTML = content;
            }
            fv.ShowDialog();
        }

        #endregion

        #region Event handlers

        private void txtUserName_Enter(object sender, EventArgs e)
        {
            if (string.Compare(txtUserName.Text, Properties.Resources.Text_UserAccountDefault, StringComparison.CurrentCultureIgnoreCase) == 0)
            {
                txtUserName.Text = string.Empty;
            }
        }

        private void txtUserName_TextChanged(object sender, EventArgs e)
        {
            ValidateUserName();
        }

        private void txtUserName_Leave(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(txtUserName.Text))
            {
                txtUserName.Text = Properties.Resources.Text_UserAccountDefault;
                txtPassword2.Enabled = false;
            }
            ValidateUserName();
        }

        private void txtPassword1_TextChanged(object sender, EventArgs e)
        {
            txtPassword2.Enabled = true;
            ValidatePassword();
        }

        private void txtPassword2_TextChanged(object sender, EventArgs e)
        {
            ValidatePassword();
        }

        private void txtPassword1_Enter(object sender, EventArgs e)
        {
            if (string.Compare(txtPassword1.Text, Properties.Resources.Text_PasswordDefault, StringComparison.OrdinalIgnoreCase) == 0)
            {
                txtPassword1.Text = string.Empty;
                txtPassword1.UseSystemPasswordChar = true;
            }
        }

        private void txtPassword1_Leave(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(txtPassword1.Text))
            {
                txtPassword1.Text = Properties.Resources.Text_PasswordDefault;
                txtPassword2.Text = Properties.Resources.Text_PasswordVerifyDefault;
                txtPassword1.UseSystemPasswordChar = false; 
                txtPassword2.UseSystemPasswordChar = false;
                txtPassword2.Enabled = true;
            }
            ValidateUserName();
        }
        
        private void txtPassword2_Enter(object sender, EventArgs e)
        {
            if (string.Compare(txtPassword2.Text, Properties.Resources.Text_PasswordVerifyDefault, StringComparison.OrdinalIgnoreCase) == 0)
            {
                txtPassword2.Text = string.Empty;
                txtPassword2.UseSystemPasswordChar = true;
            }
            ValidatePassword();
        }

        private void txtPassword2_Leave(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(txtPassword2.Text))
            {
                txtPassword2.Text = Properties.Resources.Text_PasswordVerifyDefault;
                txtPassword2.UseSystemPasswordChar = false;
                
            }
            if (string.Compare(txtPassword1.Text, Properties.Resources.Text_PasswordDefault, StringComparison.OrdinalIgnoreCase) == 0)
            {
                txtPassword2.Enabled = false;
            }
            ValidatePassword();
        }

        private void clbServerConfigItems_Leave(object sender, EventArgs e)
        {
            ValidateConfigList();
        }

        private void radWimImage_CheckedChanged(object sender, EventArgs e)
        {
            FillOSList();
            FillSysprepList();
            ValidateOsList();
            ValidateSysprepList();
            lblSysprepPackage.Text = Properties.Resources.CTSD_SysprepInfText;
        }

        private void radScriptedInstall_CheckedChanged(object sender, EventArgs e)
        {
            FillOSList();
            FillSysprepList();
            ValidateOsList();
            ValidateSysprepList();
            lblSysprepPackage.Text = Properties.Resources.CTSD_UnattendXmlText;
        }

        private void cmbOSPackage_SelectedIndexChanged(object sender, EventArgs e)
        {

            int index = cmbOSPackage.SelectedIndex - 2; // to account for the two "fake" selections at the top of the list

            if ((index > -1) && (index < osList.Count))
            {
                cmbOSPackage.Tag = osList[index];
                //modified 12/10/09 by rhearn 
                //moved setting of this property into the conditional to ensure it's set only when cbo value is valid
                selectedOsPackage = IntegrationKitUtilities.GetComboBoxControlValue(cmbOSPackage);
            }
            //modified 12/10/09 by rhearn 
            // cleared Tag property and selectedOsPackage to ensure empty values when cbo value is not valid
            else
            {
                cmbOSPackage.Tag = null;
                selectedOsPackage = string.Empty;
            }

            ValidateOsList();
        }

        private void cmbSysprepPackage_SelectedIndexChanged(object sender, EventArgs e)
        {
            int index = cmbSysprepPackage.SelectedIndex - 2; // to account for the two "fake" selections at the top of the list
            if ((index > -1) && (index < sysprepList.Count))
            {
                //modified 12/10/09 by rhearn 
                //moved setting of this property into the conditional to ensure it's set only when cbo value is valid
                cmbSysprepPackage.Tag = sysprepList[index];
                selectedOsConfigPackage = IntegrationKitUtilities.GetComboBoxControlValue(cmbSysprepPackage);
            }
            //modified 12/10/09 by rhearn 
            // cleared Tag property and selectedOsConfigPackage to ensure empty values when cbo value is not valid
            else
            {
                cmbSysprepPackage.Tag = null;
                selectedOsConfigPackage = string.Empty;
            }

            ValidateSysprepList();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnCreate_Click(object sender, EventArgs e)
        {
            if (IsPageValid() == true)
            {
                //=========[ begin modification ]====================
                // modified 9/4/08 by rhearn
                // - Changed code to branch to different method depending on whether this is a
                // - new task sequence action or a merge action.
                //
                IResultObject taskSequencePackage = null;

                if (Connection == null)
                {
                    MessageBox.Show("CreateTaskSequenceTemplate: Connection to SCCM server not set yet.");
                    return;
                }

                try
                {
                    templateXml = RemoveUnusedStepsFromTemplate(templateXml, configXml, clbServerConfigItems.CheckedItems, radScriptedInstall.Checked);
                    templateXml = ReplaceSelectionPackageIds(templateXml);
                    templateXml = CustomRebootUtils.FixPackageReferencesInTaskSequence(Connection, templateXml, configXml);
                    if (templateXml == null)
                    {
                        MessageBox.Show("An error occurred in CreateTaskSequenceTemplate(): TemplateXml was null after fixing package references.");
                        return;
                    }
                    if (taskSequenceXml == null)
                    {
                        MessageBox.Show("An error occurred in CreateTaskSequenceTemplate(): Property TaskSequenceXml was null.");
                        return;
                    }


                    if (isMergeAction == true)
                    {
                        //MessageBox.Show("isMergeAction is true"); 
                        NewTaskSequenceXml = CustomRebootUtils.MergeTaskSequencesForCustomReboot(taskSequenceXml, templateXml);
                        if (NewTaskSequenceXml == null)
                        {
                            MessageBox.Show("An error occurred in CreateTaskSequenceTemplate(): NewTaskSequenceXml was null after MergeTaskSequencesForCustomReboot().");
                            return;
                        }
                    }
                    else
                    {
                        //MessageBox.Show("isMergeAction is false");
                        NewTaskSequenceXml = templateXml;
                    }

                   
                    taskSequencePackage = CreateTaskSequenceFromUpdatedTemplate(NewTaskSequenceXml);
                    if (taskSequencePackage == null)
                    {
                        MessageBox.Show("CreateTaskSequenceTemplate: Could not create task sequence package!");
                        return;
                    }

                }
                catch (SmsException ex)
                {
                    MessageBox.Show(Properties.Resources.CTS_Exception_CreatingTaskSequence + "\n" + ex.Message + ex.InnerException + ex.Details);
                    return;
                }


               
                //=========[ end modification ]====================


                if (taskSequencePackage != null)
                {
                    string tsName = IntegrationKitUtilities.GetROStringProperty(taskSequencePackage, "Name");

                    //=========[ begin modification ]====================
                    // added 08-20-08 rhearn
                    // - changed small dialog to HTML form for better information display

                    
                    string dialogText =
                        Properties.Resources.CTSD_FinishDialogHtmlTop +
                        tsName +
                        Properties.Resources.CTSD_FinishDialogHtmlBottom;


                    FileViewer fv = new FileViewer();
                    fv.Height = 100;
                    fv.Width = 200;
                    
                    fv.Text = Properties.Resources.CTSD_FinishDialogTitle;
                    fv.EditHTML = dialogText;
                    fv.ShowDialog();

                    //if (string.IsNullOrEmpty(tsName) == false)
                    //{
                    //    MessageBox.Show(
                    //        string.Format(Properties.Resources.CTS_CompleteMessageText, tsName),
                    //        Properties.Resources.CTS_CompleteMessageCaption,
                    //        MessageBoxButtons.OK,
                    //        MessageBoxIcon.Information);
                    //}

                    //=========[ end modification ]====================


                    //===[ begin modification ]===========================
                    // Modified 9/11/08 by rhearn
                    // Added code to allow merging of existing task sequences with the template to 
                    // create the new task sequence in the same folder as the existing task sequence

                    if (consoleFolderId > 0)
                    {
                        //MessageBox.Show("ConsoleFolderID > 0 (" + consoleFolderId + ")");
                        string tsPackageId = IntegrationKitUtilities.GetROStringProperty(taskSequencePackage, "PackageID");
                        //MessageBox.Show("Task Sequence PackageId = " + tsPackageId);
                        taskSequencePackage = IntegrationKitUtilities.CreateConsoleFolderItem(Connection, tsPackageId, IntegrationKitUtilities.ContainerItemType.TaskSequencePackage, consoleFolderId);
                        if (taskSequencePackage != null)
                        {
                            IResultObject folder = IntegrationKitUtilities.GetFolderById(Connection, ConsoleFolderId);
                            base.AddRefreshResultObject(folder, PropertyDataUpdateAction.RefreshAll);
                        }
                        else
                        {
                            MessageBox.Show("Unable to place the task sequence package in the current sub-folder. It will be created in the root Task Sequences node.");
                            this.AddRefreshResultObject(null, PropertyDataUpdateAction.RefreshAll);
                        }
                    }
                    else
                    {
                        //task sequence will be created in base folder
                        base.AddRefreshResultObject(null, PropertyDataUpdateAction.RefreshAll);
                        
                        // MessageBox.Show("ConsoleFolderID !> 0 (" + consoleFolderId + ")");
                    }
                    //===[ end modification ]===========================

                }
                InvokeUpdateDelegate();

                DialogResult = DialogResult.OK;
                Close();
            }
            else
            {
                MessageBox.Show(Properties.Resources.Error_FixPageErrors);
            }
        }

        /// <summary>
        ///     
        /// </summary>
        /// <param name="sender" type="object">
        ///     <para>
        ///         
        ///     </para>
        /// </param>
        /// <param name="e" type="System.EventArgs">
        ///     <para>
        ///         
        ///     </para>
        /// </param>
        protected void btnCancel_Click(object sender, EventArgs e)
        {
            DialogResult = DialogResult.Cancel;
            Close();
        }

        /// <summary>
        ///     
        /// </summary>
        /// <param name="sender" type="object">
        ///     <para>
        ///         
        ///     </para>
        /// </param>
        /// <param name="e" type="System.EventArgs">
        ///     <para>
        ///         
        ///     </para>
        /// </param>
        protected void btnHelp_Click(object sender, EventArgs e)
        {
            // added 08-20-08 rgh : added help button and text to form for more concise display

            string dialogTitle = Properties.Resources.CTSD_HelpTitle;
            string dialogText = Properties.Resources.CTSD_HelpText;

            ShowFileViewerDialog("html", dialogTitle, dialogText);

        }

        #endregion

        #region Validation

      
        private bool IsPageValid()
        {
            if ((epUserAccount.GetError(txtUserName) == "") &&
                (epPassword1.GetError(txtPassword1) == "") &&
                (epPassword2.GetError(txtPassword2) == "") &&
                (epOsList.GetError(cmbOSPackage) == "") &&
                (epSysprep.GetError(cmbSysprepPackage) == "") &&
                (epConfigList.GetError(clbServerConfigItems) == ""))
            {
                return true;
            }
            return false;
        }

        private void ValidateUserName()
        {
            try
            {

                if (string.Compare(txtUserName.Text, 
                    Properties.Resources.Text_UserAccountDefault, 
                    StringComparison.CurrentCultureIgnoreCase) == 0)
                {
                    epUserAccount.SetError(txtUserName, "Please specify a user account.");
                    return;
                }
                if (IntegrationKitUtilities.IsValidDomainUserName(txtUserName.Text))
                {
                    epUserAccount.SetError(txtUserName, "");
                }
                else
                {
                    epUserAccount.SetError(txtUserName, @"Please specify a user account in the form of 'Domain\Username'.");
                }
                   
            }
            catch (Exception e)
            {
                //LogException(e);
                epUserAccount.SetError(txtUserName, "Exception occurred when trying to validate.\n" + e.InnerException);
            }
        }

        private void ValidatePassword()
        {
           
            if (string.Compare(txtPassword2.Text, Properties.Resources.Text_PasswordVerifyDefault, StringComparison.OrdinalIgnoreCase) == 0)
            {
                epPassword2.SetError(txtPassword2, "Password must be entered.");
            }

            if (string.Compare(txtPassword1.Text, Properties.Resources.Text_PasswordDefault, StringComparison.OrdinalIgnoreCase) == 0)
            {
                epPassword1.SetError(txtPassword1, "Password must be entered.");
            }
            else if (txtPassword1.Text.Trim().Length == 0)
            {
                epPassword1.SetError(txtPassword1, "Invalid password - cannot be blank");
            }
            else
            {
                //password box 1 has characters, so it is valid
                epPassword1.SetError(txtPassword1, "");

                if (txtPassword2.Text == txtPassword1.Text)
                {
                    //passwords match. Valid
                    epPassword2.SetError(txtPassword2, "");
                }
                else
                {
                    epPassword2.SetError(txtPassword2, "Passwords must match");
                }
            }
                
           
        }

        private void ValidateOsList()
        {
            if ((cboBusy == false) && (string.Compare(
                IntegrationKitUtilities.GetComboBoxControlValue(cmbOSPackage),
                Properties.Resources.Text_Select,
                StringComparison.OrdinalIgnoreCase) == 0))
            {
                epOsList.SetError(cmbOSPackage, "Please select an item from the list");
            }
            else
            {
                epOsList.SetError(cmbOSPackage, "");
            }
        }

        private void ValidateSysprepList()
        {
            epSysprep.SetError(cmbSysprepPackage, ""); 
            if (cmbSysprepPackage.Enabled == true)
            {

                if ((cboBusy == false) && (string.Compare(
                    IntegrationKitUtilities.GetComboBoxControlValue(cmbSysprepPackage),
                    Properties.Resources.Text_Select,
                    StringComparison.OrdinalIgnoreCase) == 0))
                {
                    epSysprep.SetError(cmbSysprepPackage, "Please select an item from the list");
                }
                else
                {
                    epSysprep.SetError(cmbSysprepPackage, "");
                }
            }
        }

        //=========[ added 12/16/08 by rhearn to ensure validation of config selections ]=============/
        private void ValidateConfigList()
        {
            epConfigList.SetError(clbServerConfigItems, "");
            if (clbServerConfigItems.CheckedItems.Count > 0)
            {
                epConfigList.SetError(clbServerConfigItems, "");
            }
            else
            {
                epConfigList.SetError(clbServerConfigItems, "Please select an item from the list");
            }
        }

        #endregion


        

        

        

       
        

    }
}
